namespace Xrm.Solutions.FrameworkSample.Plugins
{
    using System;
    using System.ServiceModel;
    using Microsoft.Xrm.Sdk;
    using Xrm.Solutions.FrameworkSample.Common;
    using Xrm.Solutions.FrameworkSample.Common.Entities;

    /// <summary>
    /// Plugin to generate a score for the related contact.
    /// </summary>    
    public class RunIdentityCheck: Plugin
    {
        public RunIdentityCheck()
            : base(typeof(RunIdentityCheck))
        {
            base.RegisteredEvents.Add(new Tuple<int, string, string, Action<LocalPluginContext>>(40, "Create", "xdft_identitycheck", new Action<LocalPluginContext>(ExecuteRunIdentityCheck)));
        }

        protected void ExecuteRunIdentityCheck(LocalPluginContext localContext)
        {
            Entity identityCheck = GetIdentityCheck(localContext);

            string firstname = identityCheck.Contains("xdft_firstname") ? identityCheck["xdft_firstname"].ToString() : null;
            string lastname = identityCheck.Contains("xdft_lastname") ? identityCheck["xdft_lastname"].ToString() : null;
            DateTime dob = identityCheck.Contains("xdft_dateofbirth") ? (DateTime)identityCheck["xdft_dateofbirth"] : DateTime.MaxValue;
            string address = identityCheck.Contains("xdft_address") ? identityCheck["xdft_address"].ToString() : null;

            IdentityCheckService service = new IdentityCheckService();
            int score = service.RunCheck(firstname,
                                        lastname,
                                        dob,
                                        address);

            localContext.TracingService.Trace("Score has been generated. Value: {0}", score);

            Entity updatedContact = new Entity("contact");
            updatedContact.Id = ((EntityReference)identityCheck["xdft_contactid"]).Id;
            updatedContact["xdft_identityscore"] = score;

            localContext.OrganizationService.Update(updatedContact);
        }

        private Entity GetIdentityCheck(LocalPluginContext localContext)
        {
            if (localContext == null)
                throw new ArgumentNullException("localContext");
           
            if (!localContext.PluginExecutionContext.InputParameters.Contains("Target"))
                throw new ArgumentNullException("Target");

            Entity identityCheckEntity = (Entity)localContext.PluginExecutionContext.InputParameters["Target"];
            if(!identityCheckEntity.Contains("xdft_contactid"))
                throw new ArgumentNullException("Contact", "The current Identity Check record doesn't have an associated contact");
                         
            localContext.TracingService.Trace("Identity Check is ready to be used");

            return identityCheckEntity;
        }
    }
}
